package com.sanq.product.books.service.impl;

import com.google.common.collect.Lists;
import com.sanq.product.books.config.Redis;
import com.sanq.product.books.entity.vo.BlockJoinBooksVo;
import com.sanq.product.books.entity.vo.BooksVo;
import com.sanq.product.books.entity.vo.SortJoinBooksVo;
import com.sanq.product.books.entity.vo.SortVo;
import com.sanq.product.books.kafka.producer.service.BooksMQService;
import com.sanq.product.books.mapper.BlockJoinBooksMapper;
import com.sanq.product.books.mapper.BooksMapper;
import com.sanq.product.books.mapper.SortJoinBooksMapper;
import com.sanq.product.books.mapper.SortMapper;
import com.sanq.product.books.service.BooksService;
import com.sanq.product.config.utils.entity.Pager;
import com.sanq.product.config.utils.entity.Pagination;
import com.sanq.product.config.utils.string.StringUtil;
import com.sanq.product.config.utils.web.JsonUtil;
import com.sanq.product.redis.service.JedisPoolService;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;


@Service("booksService")
public class BooksServiceImpl implements BooksService {

    @Resource
    private BooksMapper booksMapper;
    @Resource
    private BlockJoinBooksMapper blockJoinBooksMapper;
    @Resource
    private JedisPoolService jedisPoolService;
    @Resource
    private ThreadPoolTaskExecutor taskExecutor;
    @Resource
    private SortMapper sortMapper;
    @Resource
    private SortJoinBooksMapper sortJoinBooksMapper;
    @Resource
    private BooksMQService booksMQService;

    public void deleteRedis(Long booksId) {
        taskExecutor.execute(() -> {
            String key = Redis.ReplaceKey.getBooksDetailKey(booksId);
            jedisPoolService.delete(key);
        });
    }

    @Override
    public int save(BooksVo booksVo) {
        return booksMapper.save(booksVo);
    }

    @Override
    public int delete(BooksVo booksVo) {
        int delete = booksMapper.delete(booksVo);
        if (delete != 0) {
            if (booksVo.getId() != null) {
                deleteRedis(booksVo.getId());
            } else deleteRedis(-1L);
        }
        return delete;
    }

    @Override
    public int update(BooksVo booksVo, Long id) {
        BooksVo oldBooksVo = findById(id);

        if (null != oldBooksVo && null != booksVo) {
            if (null != booksVo.getId()) {
                oldBooksVo.setId(booksVo.getId());
            }
            if (null != booksVo.getBooksName()) {
                oldBooksVo.setBooksName(booksVo.getBooksName());
            }
            if (null != booksVo.getAuthor()) {
                oldBooksVo.setAuthor(booksVo.getAuthor());
            }
            if (null != booksVo.getSortId()) {
                oldBooksVo.setSortId(booksVo.getSortId());
            }
            if (null != booksVo.getBooksCover()) {
                oldBooksVo.setBooksCover(booksVo.getBooksCover());
            }
            if (null != booksVo.getBooksDescription()) {
                oldBooksVo.setBooksDescription(booksVo.getBooksDescription());
            }
            if (null != booksVo.getCreateTime()) {
                oldBooksVo.setCreateTime(booksVo.getCreateTime());
            }
            if (!StringUtil.isEmpty(booksVo.getIsOver())) {
                oldBooksVo.setIsOver(booksVo.getIsOver());
            }
            if (!StringUtil.isEmpty(booksVo.getReaderSex())) {
                oldBooksVo.setReaderSex(booksVo.getReaderSex());
            }

            int update = booksMapper.update(oldBooksVo);
            if (update != -1)
                deleteRedis(id);
            return update;
        }
        return 0;
    }

    @Override
    public BooksVo findById(Long id) {
        String key = Redis.ReplaceKey.getBooksDetailKey(id);
        String json = jedisPoolService.get(key);

        BooksVo booksVo;
        if (StringUtil.isEmpty(json)) {
            booksVo = booksMapper.findById(id);
            if (booksVo != null)
                jedisPoolService.set(key, JsonUtil.obj2Json(booksVo));
        } else booksVo = JsonUtil.json2Obj(json, BooksVo.class);

        return booksVo;
    }

    @Override
    public List<BooksVo> findList(BooksVo booksVo) {
        return booksMapper.findList(booksVo);
    }

    @Override
    public Pager<BooksVo> findListByPage(BooksVo booksVo, Pagination pagination) {
        pagination.setTotalCount(findCount(booksVo));

        List<BooksVo> datas = booksMapper.findListByPage(booksVo, pagination.getStartPage(), pagination.getPageSize());

        return new Pager<BooksVo>(pagination, datas);
    }

    @Override
    public int findCount(BooksVo booksVo) {
        return booksMapper.findCount(booksVo);
    }

    @Override
    public void saveByList(List<BooksVo> booksVos) {
        booksMapper.saveByList(booksVos);
    }

    @Override
    public Pager<BooksVo> findBooksByBlockId(Integer blockId, Pagination pagination) {
        String totalKey = Redis.ReplaceKey.getBooksListBlockPage(blockId + "", "-1");
        String listKey = Redis.ReplaceKey.getBooksListBlockPage(blockId + "", pagination.getCurrentIndex() + "");


        String totalJson = jedisPoolService.get(totalKey);
        String listJson = jedisPoolService.get(listKey);

        int totalCount;
        List<BooksVo> datas;

        if (StringUtil.isEmpty(totalJson) || StringUtil.isEmpty(listJson)) {
            BlockJoinBooksVo params = new BlockJoinBooksVo();
            params.setBlockId(blockId);
            totalCount = blockJoinBooksMapper.findCount(params);

            pagination.setTotalCount(totalCount);

            datas = booksMapper.findBooksByBlockId(blockId, pagination.getStartPage(), pagination.getPageSize());
            if (totalCount != 0 && !datas.isEmpty()) {
                jedisPoolService.set(totalKey, totalCount + "");
                jedisPoolService.set(listKey, JsonUtil.obj2Json(datas));
            }
        } else {
            totalCount = StringUtil.toInteger(totalJson);
            pagination.setTotalCount(totalCount);

            datas = JsonUtil.json2ObjList(listJson, BooksVo.class);
        }

        return new Pager<BooksVo>(pagination, datas);
    }


    @Override
    public Pager<BooksVo> findListBySortIds(List<String> sortIds, Pagination pagination) {
        pagination.setTotalCount(findListCountBySortIds(sortIds));

        List<BooksVo> datas = booksMapper.findListBySortIds(sortIds, pagination.getStartPage(), pagination.getPageSize());
        return new Pager<BooksVo>(pagination, datas);
    }

    public int findListCountBySortIds(List<String> sortIds) {
        return booksMapper.findListCountBySortIds(sortIds);
    }

    @Override
    public void saveBooks(long l) {
        List<BooksVo> booksVoList = Lists.newArrayListWithCapacity(StringUtil.toInteger(l));

        List<String> list = jedisPoolService.getList(Redis.RedisKey.SPLIDE_BOOKS_LIST_KEY, 0, l);

        if (0L != l) {
            List<SortJoinBooksVo> saveSortJoinBooksList = new ArrayList<>();
            list.stream().filter(tmp -> !StringUtil.isEmpty(tmp)).forEach(tmp -> {
                BooksVo booksVo = JsonUtil.json2Obj(tmp, BooksVo.class);
                // 设置分类 阅读人群
                String tmpSortName = booksVo.getTmpSortName();

                if (!StringUtil.isEmpty(tmpSortName)) {
                    List<SortVo> sortVos = sortMapper.findListBySortName(tmpSortName);

                    if (sortVos != null && !sortVos.isEmpty()) {
                        booksVo.setReaderSex(sortVos.get(0).getBlockId());
                        booksVo.setSortId(sortVos.get(0).getParentId());

                        List<SortJoinBooksVo> sortJoinBooksVoList = Lists.newArrayListWithCapacity(sortVos.size());

                        sortVos.forEach(sortVo -> {
                            SortJoinBooksVo sortJoinBooksVo = new SortJoinBooksVo();
                            sortJoinBooksVo.setSortId(sortVo.getId());
                            sortJoinBooksVo.setBooksId(booksVo.getId());
                            sortJoinBooksVoList.add(sortJoinBooksVo);
                        });

                        saveSortJoinBooksList.addAll(sortJoinBooksVoList);
                    }
                }

                booksVoList.add(booksVo);
            });

            booksMapper.saveByList(booksVoList);
            sortJoinBooksMapper.saveByList(saveSortJoinBooksList);
            jedisPoolService.rmList(Redis.RedisKey.SPLIDE_BOOKS_LIST_KEY, list.size());

            booksMQService.save2Es(booksVoList, "SPLIDE");

        } else {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }


    }
}